﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Configuration;
using Jobping.ShortUrls.Models;
using System.Transactions;

namespace Jobping.ShortUrls.Controllers
{
    [HandleError, ValidateInput(false)]
    public class HomeController : Controller
    {
		int encoderOffset = 0;

        DbDataContext db = new Models.DbDataContext(MvcApplication.ConnectionString);
        ShortUrlEncoder encoder = new ShortUrlEncoder();
		LongUrlValidator validator = new LongUrlValidator() 
		{ 
			ValidDomains= ConfigurationManager.AppSettings["DomainsWeShorten"].Split( new char[1] {','},StringSplitOptions.RemoveEmptyEntries)
		};

		public HomeController()
		{
			string offset = ConfigurationManager.AppSettings["EncoderOffset"];

			if (offset == null || !Int32.TryParse(offset, out encoderOffset))
				encoderOffset = 0;

		}

        [HttpGet]
        public ActionResult Index()
        {
			return View((object)String.Empty);
        }

        [HttpPost]
        public ActionResult Index(string longUrl, string format)
        {
			string error = validator.Validate(longUrl);
			
			if (error != null)
			{
				this.ModelState.AddModelError("Url", error);
				return View((object)longUrl);
			}

            var url = db.GetByLongUrl(longUrl);
                
            if (url == null)
            {
                url = new Url();
                url.LongUrl = longUrl;
                url.DateCreated = DateTime.UtcNow;

                using (TransactionScope transScope = new TransactionScope())
                {
                    db.Urls.InsertOnSubmit(url);
                    db.SubmitChanges();
                    string virtualUrl = this.encoder.Encode(url.Id + encoderOffset);
                    url.ShortUrl = new Uri(this.Request.Url, virtualUrl).ToString();
                    db.SubmitChanges();
                    transScope.Complete();
                }
            }

            //Return text only if desired
            if (!String.IsNullOrEmpty(format) && format.ToUpper() == "TXT")
            {
                return View("Result.TXT", url);
            }

            return View("Result", url);
        }

        public ActionResult Follow(string shortUrl)
        {
            shortUrl = new Uri(this.Request.Url, shortUrl).ToString();

            var dbUrl =db.GetByShortUrl(shortUrl);

            if (dbUrl == null)
            {
                Response.StatusCode = 404;
                return View("404");
            }

			string url = dbUrl.LongUrl;
			string referrer = this.Request.UrlReferrer != null ? this.Request.UrlReferrer.ToString() : this.Request.Url.ToString();

			url = url +  (url.Contains('?') ? "&" : "?") + "Referer=" + Server.UrlEncode(referrer);

            this.Response.Status = "301 Moved Permanently";
            this.Response.StatusCode = 301;
            this.Response.AppendHeader("Location", url);

            return null;
        }

        public ActionResult About()
        {
            return View();
        }
    }
}
